Un ejemplo de 15 minutos para entender el Runtime Environment de Javascript

Al ser programador de Javascript tarde o temprano te encontrarás con algo o alguien que te platiqué acerca de un nuevo runtime environment (ambiente/entorno de ejecución) de Javascript. Tal vez mencione las bondades del mismo o diga que por x o y razon será mejor que los otros…

Tal vez tu ya sepas qué es y en ese caso pues ya vas de gane. Pero tal vez seas como alguna vez yo fui y te quedes con cara de…¿kha?

¿De qué estan hablando exactamente?

El problema es que uno como desarrollador de Javascript uno no suele tener presente esta clase de cosas y generalmente va por 1 de 2 caminos:

  • Programa un front-end y lo prueba en algunos navegadores.
  • Programa un back-end con NodeJS o algo del estilo y lo prueba en su terminal.

En ninguna de las 2 opciones se necesita tener noción de algo más. Y por ende muchos desarrolladores nos quedamos sin una pieza vital de información. No obstante es interesante saber qué estamos utilizando realmente.

Runtime Environment (Ambiente de ejecución)

Un runtime environment es en pocas palabras el lugar donde se ejecuta tu código.

¿Qué tanto lugares puede haber?

Pues de entrada ya mencioné 2 muy conocidos: los navegadores y NodeJS.

El navegador que utilices sea cual sea se juega el papel de runtime environment.

Chrome, Edge, Firefox, Opera, el que sea.

“Oye pero si yo estoy utilizando mi editor de código para correr el proyecto entonces…ese es mi ambiente de ejecución?” ¡No, claro que no!

Tu editor de código simplemente funge como el lugar donde puedes ver los archivos de tu proyecto. No tiene nada que ver.

*Para refrescar la memoria acerca de como es el proceso de compilado del lenguaje y que archivos finalmente son los que se le pasan al navegador te recomiendo leer: Las diferencias entre un lenguaje compilado e interpretado en 10 minutos.

Ahora no olvidemos que tambien mencionamos a NodeJS.

¿Esto quiere decir que NodeJS es como un navegador? Emmm…en parte.

Evidentemente no tiene la misma función que un navegador. Como mencioné al principio, NodeJS se utiliza para la parte del back-end sobre todo para APIs.

Pero así como Chrome o Edge tienen la capacidad de ejecutar el código de Javascript, NodeJS también puede hacerlo..

¿Cuál es la diferencia entre ejecutar tu código en un navegador o en un runtime como NodeJS?

La respuesta corta es: La funcionalidad disponible

Ejemplo

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <form>
            <input type="button" value="Open Window" onclick="openWin()">
            <input type="button" value="Open Alert" onclick="openAlert()">
        </form>

        <script type="text/javascript" src="src/runtimeEnvironments/browserFeaturesExample.js"></script>
    </body>
</html>
function openWin() {
    window.open("https://developer.mozilla.org/en-US/docs/Web/API/Window");
}

function openAlert() {
    alert('Alert is working');
}

La función alert si bien no es muy usada para código en producción (es decir para sitos y apps ya lanzadas al público), es ampliamente conocida porque es de lo que más se usa mientras aprendemos JS.

Por otro lado window es un objeto muy importante en el navegador, ya que es el que se asigna como objeto global en el código. Esto porsupuesto permite que se utilize para un gran número de cosas. (Aunque en nuestro ejemplo solo esta siendo usado para abrir una nueva ventana).

*Si no estas familiarizado con el objeto global hechale un vistazo a:
Lo que necesitas saber de this en Javascript

Y si quieres algo mas avanzado:
El único ejemplo que necesitas para entender Global Execution Context en Javascript

Porsupuesto este código no tiene nada de especial. Si utilizamos el código HTML como index y lo corremos en el navegador veremos un par de botones que deberán abrir un nuevo sitio y desplegar una alerta respectivamente.

Pero la pregunta es si corremos este código de Javascript en NodeJS. ¿Funcionará?

*Para empezar con NodeJS ve a https://nodejs.org/en

Para probarlo necesitamos hacer un pequeño cambio en el código, ya que NodeJS no cuenta con interfaz gráfica y por ende no podremos llamar a las funciones mediante botones.

function openWin() {
    window.open("https://developer.mozilla.org/en-US/docs/Web/API/Window");
}

function openAlert() {
    alert('Alert is working');
}

setTimeout(() => {
    openWin()
}, 2000)

setTimeout(() => {
    openAlert()
}, 4000)

Listo. El único cambio fue hacer que el código llame automáticamente a las 2 funciones tras un retraso de 2 segundos para una y de 4 segundos para la otra.

Para llamar a node simplemente basta con utilizar la keyword node y la ruta hacia el archivo que quieres ejecutar:

node src/runtimeEnvironments/browserFeaturesNodeJS.js

¿Qué es lo que ocurre entonces?

    window.open("https://developer.mozilla.org/en-US/docs/Web/API/Window");
    ^

ReferenceError: window is not defined

NodeJS nos lanzá un error de que no encuentra el objeto window.

Y…probablemente esto no te sorprenda. Pero pasará lo mismo con alert.

function openWin() {
    window.open("https://developer.mozilla.org/en-US/docs/Web/API/Window");
}

function openAlert() {
    alert('Alert is working');
}

// Comentamos esta sección para poder ignorar el error de window y probar con alert
// setTimeout(() => {
//     openWin()
// }, 2000)

setTimeout(() => {
    openAlert()
}, 4000)
alert('Alert is working');
    ^
ReferenceError: alert is not defined

Tiene sentido cuando lo piensas.

NodeJS no esta hecho para trabajar con una interfaz gráfica que mostrarle al usuario. Por ende no tiene sentido que tenga definidas las implementaciondes de window y alert.


Esto que acabas de ver son los APIs a los que un runtime environment tiene acceso. No importa en que navegador ejecutes las llamadas a window o alert. El mismo navegador pone a disponibilidad de JS los llamados Web APIs lo cuál permite que utilices las funciones y objetos de los ejemplos.

Una vez aprendiendo esto, tal vez te preguntes…¿acaso todos los navedagores hacen lo mismo? ¿Qué se ponen de acuerdo o que onda? Y si. Eso hacen. Los navegadores se rigen por un estándar. El estándar W3C para ser exactos.

Porsupuesto tampoco lo olvides pero NodeJS también hace su propia magia y pone a disposición funciones y objetos útiles para los propósitos de back-end. Sin embargo esa parte será un tema para otro momento.

Ahora ya sabes que es un runtime environment. Es interesante ver que aunque hagamos el programa mas simple que nos podamos imaginar nunca estamos utilizando solo JS realmente.

Dicho esto ahora el siguiente paso sería que aprendieras cuáles son las partes que componen al Runtime Environment. Ya vimos 1, los APIs. Pero hay algunas más que vale la pena conocer: Las partes que componen al Runtime Environment de Javascript.